<?php

namespace Boosen\Company\app\Console\Commands;

use Illuminate\Console\Command;

use Boosen\Company\app\Models\Company;
use Boosen\Company\app\Models\CNBaseProductUrl;
use Boosen\Company\app\Models\CNTmpCategory;

class CNBaseProductUrlSpider extends Command
{
    const PAGE_SIZE = 10;
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'cn:base_product_url {start_id?}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $startId = $this->argument('start_id') ?: 1;
        $page = 1;
        
        while (true) {
            $companies = Company::where('id', '>=', $startId)->simplePaginate(self::PAGE_SIZE, ['*'], 'page', $page);

            $break = (bool)!(count($companies->items()) > 0);

            foreach ($companies->items() as $company) {
                $break = !$this->processUrl($company);
                if ($break) break;

                $this->info($company->id . 'th done.');
                if ($company->id % 3) {
                    sleep(2);
                }
            }
            if ($break) break;
            $page++;

        }
    }


    private function processUrl($company)
    {
        // $url = 'https://laser88888.cn.china.cn';
        $url = $company->companyUrl->url;
        $url .= '/supply';

        $goutte = GoutteClient::getInstance();
        while (true) {
            try {
                $client = $goutte->client();
                $crawler = $client->request('GET', $url);
                $cateItems = $crawler->filterXPath('//div[@class="assists "]/ul/li/a');

                if ($cateItems->count() == 0) {
                    $cateItems = $crawler->filterXPath('//div[@class="assists hidenstate"]/ul/li/a');
                }

                $cateItems = $cateItems->reduce(function($item, $i) {
                    if (false !== mb_strpos($item->text(), '全部')) {
                        return false;
                    }
                    return true;
                });

                $arr = $cateItems->each(function($item, $i) use ($company) {
                    $text = trim($item->text());
                    $pos = mb_strpos($text, '(');
                    $name = ($pos !== false) ? mb_substr($text, 0, $pos) : $text;
                    $url = $item->link()->getUri();
                    $cate = CNTmpCategory::updateOrCreate(['name' => $name]);

                    $res = CNBaseProductUrl::updateOrCreate(['company_id' => $company->id, 'c_id' => $cate->id], [
                        'url' => $url
                    ]);

                    $this->info('insert new one ' . $res->id . 'th ' . $cate->name);
                });
                break;
            } catch (\Exception $e) {
                $this->info($e->getMessage());

                if ($crawler->filterXPath('//div[@class="warn_cont"]')->count()) {
                    $gutte->changeProxy();
                    $this->info('proxy change to ' . $gutte->getProxy());
                } else {
                    // insert error message to DB

                    return false;
                }

                if (false !== strposa($e->getMessage(), array('time out', 'timed out', 'reset', 'aborted', 'refused'))) {
                    if ($gutte->hasProxy()) {
                        $gutte->unsetProxy();
                    }

                    if ($gutte->proxyCount() == 0) {
                        $this->info('no useful proxy ');
                        sleep(10);
                    }
                }

            }
        }

        return true;
    }
}
